package com.isky.visual.design.sqlparsefactory;

import com.isky.visual.db.entity.*;
import com.isky.visual.exception.GlobalException;
import com.isky.visual.result.CodeMsg;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * @Author wenjs
 * SQLServer sql parse
 */
public class SQLServerSqlParse extends AbstractSqlParse {

    final String AS = "as";
    final String DEFAULT_JOIN = "join";
    final String JOIN_TYPE = "inner,cross,left,right,outer";
    final String ON = "on";
    final String AND = "and";
    final String IFNULL="IFNULL";
    final Integer IFNULL_DEFAULT = 0;


    @Override
    public void doParseMain(VclList vclList ,String dbname) {
        if (vclList == null) {
            return;
        }

        String tableName = vclList.getTablename();

        if (StringUtils.isEmpty(tableName)) {
            return;
        }

        String alias = getAlias(tableName);
        tableName = String.format("%s %s %s", tableName, AS, alias);

        appendMainTable(tableName);
    }

    /**
     * 处理子节点 join结构
     *
     * @param child
     * @param parentTableName
     */
    @Override
    protected void doParseChildren(Children child, String parentTableName,String dbname) {
        if (child == null || StringUtils.isEmpty(parentTableName) ||
                StringUtils.isEmpty(child.getTablename()) ) {
            return;
        }

        CodeMsg codeMsg = CodeMsg.MODE_JSON_FORMAT_JOIN_ERROR.Clone();
        codeMsg.setMsg(String.format("表%s:%s",child.getTablename(),codeMsg.getMsg()));

        LinkObj linkObj = child.getLinkObj();
        if (linkObj == null) {
            throw new GlobalException(codeMsg);
        }

        String checkstyle = linkObj.getCheckstyle();
        String CandidateCheckstyle = DEFAULT_JOIN;
        if (StringUtils.isEmpty(checkstyle)) {
            checkstyle = DEFAULT_JOIN;
        } else { //检测常用join方式
            String firstKey = "";
            String secondKey = "";
            checkstyle = checkstyle.trim().toLowerCase();

            // 检测是否 "left join" 这种格式
            String[] keys = checkstyle.split(" ");
            if (keys.length == 2) {
                if (!JOIN_TYPE.contains(keys[0])) {
                    //前缀不对 则不处理
                    return;
                }

                // 第二个参数是否为 join
                if (!DEFAULT_JOIN.equals(keys[1])) {
                    //不是join 则不处理
                    return;
                }
            } else if (keys.length == 1) {
                //只有 一个参数，检测是否为前缀 或者 join
                if (JOIN_TYPE.contains(keys[0])) {
                    checkstyle += " " + DEFAULT_JOIN;
                } else if (!DEFAULT_JOIN.equals(keys[0])) {
                    //格式不对 则不处理
                    return;
                }
            } else {
                //不对的格式
                return;
            }
        }

        // 解析关联条件
        List<LinkArray> linkArray = linkObj.getLinkArray();
        if (linkArray == null || linkArray.isEmpty()) {
            //没有条件，不处理
            throw new GlobalException(codeMsg);
        }

        final String tableName = child.getTablename();
        final String childAlias = getAlias(tableName);
//        final String parentAlias = getAlias(parentTableName);

        //默认左条件为父节点 ，右条件为子节点
        String joinDefinitation = "";
        for (LinkArray link : linkArray) {
            String leftColumn = link.getLeftcolumn();
            String rightColumn = link.getRightcolumn();
            String symbol = link.getSymbol();
            if (StringUtils.isEmpty(leftColumn) || StringUtils.isEmpty(rightColumn) || StringUtils.isEmpty(symbol)) {
                //条件不全，不处理
                throw new GlobalException(codeMsg);
            }

            String operator = ON;
            if (!StringUtils.isEmpty(joinDefinitation)) {
                operator = AND;
            }
            String[] leftColumns = leftColumn.split("\\.");
            String[] rightColumns = rightColumn.split("\\.");
            if (!(leftColumns.length == 2 && rightColumns.length == 2)) {
                //参数格式不对，不处理
                throw new GlobalException(codeMsg);
            }

            final String leftAlias = getAlias(leftColumns[0]);
            final String rightAlias = getAlias(rightColumns[0]);

            joinDefinitation += String.format("%s %s.%s %s %s.%s ",
                    operator, leftAlias, leftColumns[1], symbol, rightAlias, rightColumns[1]);
        }

        //解析完成，添加到joinSql缓存
        joinDefinitation = String.format("%s %s %s %s %s ",
                checkstyle, tableName, AS, childAlias, joinDefinitation);
        appendJoinSql(joinDefinitation);

        if(checkstyle.contains("outer")){
            outerCount++;
        }
    }

    /**
     * 解析select
     *
     * @param indexObj
     */
    @Override
    protected void doParseSelect(IndexObj indexObj) {
        String weidu = null;
        if (indexObj == null) {
            return;
        }

        List<SelectList> selectList = indexObj.getSelectList();
        if (selectList == null) {
            return;
        }

        List<WeiduList> weiduList = indexObj.getWeiduList();

        //循环解析column
        int parseIndex = 0;
        for (SelectList select : selectList) {
            String column = select.getColumn();
            if (StringUtils.isEmpty(column)) {
                parseIndex++;
                continue;
            }
            //查看列名称是否是table.column 格式 ，非这种格式不解析
            String[] columns = column.split("\\.");
            String  fieldName = "";
            if (columns.length == 2) {
                String tableName = columns[0];
                column = columns[1];
                if (!StringUtils.isEmpty(tableName)) {
                    String alias = getAlias(tableName);
                    column = String.format("%s.%s ", alias, columns[1]);
                    fieldName = String.format("%s_%s ", alias, columns[1]);
                }
                // 处理聚合函数
                String varia = select.getVaria();
                if (!StringUtils.isEmpty(varia)) {
                    varia = varia.toLowerCase()
                            .replace("stddev_samp","STDEV")
                            .replace("var_pop","STDEVP")
                            .replace("stddev_pop","VAR")
                            .replace("stddev","VARP") ;

                    column = String.format("%s(%s(%s),%s) %s %s ",IFNULL, varia, column,IFNULL_DEFAULT,AS,fieldName);
                }

                appendSelectColumn(column);
            }

            parseIndex++;
        }
        // 维度
        if (weiduList != null)
        {
            for (int i = 0 ; i<weiduList.size();i++)
            {
                if (i<=3)
                {
                    String[] weidus = weiduList.get(i).getWeidu().split("\\.");
                    if (weidus.length > 2) {
                        parseIndex++;
                        continue;
                    } else if (weidus.length == 2) {
                        String tableName = weidus[0];

                        if (!StringUtils.isEmpty(tableName)) {
                            String alias = getAlias(tableName);
                            weidu  = String.format("%s.%s ", alias,weidus[1]);
                            appendGroupSql(weidu);
                        }
                    }


                }
            }
        }
    }

    /**
     * 解析where 条件后
     *
     * @param sizerObj
     */
    @Override
    protected void doParseWhere(SizerObj sizerObj) {

        // 支持以下格式
        //appendWhereSql(" 1=1");
        //appendWhereSql("1=2");
        if (sizerObj == null) {
            return;
        }
        List<SelectList> selectList = sizerObj.getSelectList();
        for (SelectList slist : selectList) {
            String[] table = slist.getColumn().split("\\.");

            String where = String.format(" %s %s '%s' %s ",
                    getSplitTable(table),
                    slist.getSymbol(),
                    slist.getVal(),
                    slist.getVaria()
            );
            appendWhereSql(where);
        }
    }
    public String getSplitTable(String[] tables) {
        String table = tables[0];
        String aliasTable = getAlias(table);
        return aliasTable + "." + tables[1];
    }

}
